library(tidyverse)
library(data.table)
library(ggh4x)
library(lme4)
library(car)
library(ggeffects)
library(doParallel)
cores <- getOption("mc.cores", detectCores()) # for parallel computation
cl <- makeCluster(cores)
registerDoParallel(cl)
data loading
files <- dir("exp1_data_eyetracking_individual_saccades", ".*csv$", full.names = TRUE)
dat <- c()
for (i in 1:length(files)) {
d <- fread(files[i], header = TRUE)
d$id <- i # numeric variable for subject id
dat <- rbind(dat, d)
}
dat <- subset(dat, dat$event == "fixation")
dat <- mutate(dat, target = apply(dat, 1, function(x){names(d)[13 + which.max(x[14:16])]}))
dat <- mutate(dat, dud = apply(dat, 1, function(x){names(d)[13 + which.min(x[14:16])]}))
dat$Condition <- as.factor(dat$Condition)
dat$target <- fct_recode(dat$target, up = "UVal", left = "LVal", right = "RVal")
dat$dud <- fct_recode(dat$dud, up = "UVal", left = "LVal", right = "RVal")
dat <- mutate(dat, fix = ifelse(item == target, "target",
ifelse(item == dud, "dud",
ifelse(item == "noFix", "noFix", "distractor"))))
subject-wise fixation plot
plot1 <- foreach(i = 1:length(files), .packages = c("tidyverse", "ggh4x")) %dopar% {
subset(dat, dat$id == i) %>%
ggplot() + geom_point(aes(x = x, y = y, size = dur, color = Condition), alpha = 0.3) +
facet_nested(. ~ target + dud) + ggtitle(i) -> p
print(p)
}
plot1
## [[1]]

##
## [[2]]

##
## [[3]]

##
## [[4]]

##
## [[5]]

##
## [[6]]

##
## [[7]]

##
## [[8]]

##
## [[9]]

##
## [[10]]

Position-based fixation frequency
dat %>%
group_by(Condition, target, dud, item, id) %>%
summarise(n = n()) -> freq
## `summarise()` has grouped output by 'Condition', 'target', 'dud', 'item'. You
## can override using the `.groups` argument.
plot2 <- foreach(i = unique(freq$Condition), .packages = c("tidyverse", "ggh4x")) %dopar% {
p <- ggplot(subset(freq, freq$Condition == i)) + geom_violin(aes(x = item, y = n, color = item)) + geom_point(aes(x = item, y = n)) +
facet_nested(. ~ target + dud) +
scale_x_discrete(limits = c("up", "left", "right", "noFix")) +
scale_color_discrete(limits = c("up", "left", "right", "noFix")) + ggtitle(i)
print(p)
}
plot2
## [[1]]
## Warning: Groups with fewer than two data points have been dropped.

##
## [[2]]

##
## [[3]]

##
## [[4]]

##
## [[5]]

##
## [[6]]

Stimulus-based fixation frequency
dat %>%
group_by(Condition, fix, id) %>%
summarise(n = n()) -> fixation
## `summarise()` has grouped output by 'Condition', 'fix'. You can override using
## the `.groups` argument.
fixation$fix <- as.factor(fixation$fix)
fixation$fix <- factor(fixation$fix, levels = c("target", "distractor", "dud", "noFix"))
ggplot(fixation, aes(x = fix, y = n, color = Condition)) + geom_violin() +
geom_point(position = position_dodge(width = .9)) +
stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9))
## Warning: The `fun.y` argument of `stat_summary()` is deprecated as of ggplot2 3.3.0.
## ℹ Please use the `fun` argument instead.

f1 <- lmer(n ~ fix * Condition + (1 + fix + Condition | id), data = fixation)
## boundary (singular) fit: see help('isSingular')
summary(f1)
## Linear mixed model fit by REML ['lmerMod']
## Formula: n ~ fix * Condition + (1 + fix + Condition | id)
## Data: fixation
##
## REML criterion at convergence: 2035.6
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.7493 -0.4887 -0.0345 0.4721 4.2394
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## id (Intercept) 7676.65 87.617
## fixdistractor 48.79 6.985 0.09
## fixdud 3970.27 63.010 -0.97 0.12
## fixnoFix 13693.88 117.021 -0.92 -0.04 0.86
## Condition0.3 48.40 6.957 0.53 -0.06 -0.45 -0.75
## Condition0.5 86.03 9.275 0.86 0.43 -0.72 -0.91 0.67
## Condition0.7 102.00 10.100 0.96 0.11 -0.89 -0.98 0.62 0.92
## Condition0.85 258.02 16.063 0.79 -0.11 -0.75 -0.92 0.58 0.77
## Condition0.95 373.44 19.325 0.82 -0.04 -0.77 -0.91 0.49 0.78
## Residual 365.58 19.120
##
##
##
##
##
##
##
##
## 0.92
## 0.93 0.99
##
## Number of obs: 239, groups: id, 10
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 395.600 28.359 13.950
## fixdistractor -22.000 8.831 -2.491
## fixdud -381.514 21.788 -17.511
## fixnoFix -5.900 37.980 -0.155
## Condition0.3 -16.800 8.829 -1.903
## Condition0.5 -27.500 9.040 -3.042
## Condition0.7 -39.200 9.128 -4.295
## Condition0.85 -32.700 9.946 -3.288
## Condition0.95 -31.700 10.510 -3.016
## fixdistractor:Condition0.3 5.700 12.093 0.471
## fixdud:Condition0.3 60.814 12.279 4.952
## fixnoFix:Condition0.3 26.200 12.093 2.167
## fixdistractor:Condition0.5 2.500 12.093 0.207
## fixdud:Condition0.5 110.814 12.279 9.024
## fixnoFix:Condition0.5 39.400 12.093 3.258
## fixdistractor:Condition0.7 -1.700 12.093 -0.141
## fixdud:Condition0.7 199.014 12.279 16.207
## fixnoFix:Condition0.7 52.600 12.093 4.350
## fixdistractor:Condition0.85 -16.000 12.093 -1.323
## fixdud:Condition0.85 253.814 12.279 20.670
## fixnoFix:Condition0.85 45.600 12.093 3.771
## fixdistractor:Condition0.95 -32.100 12.093 -2.655
## fixdud:Condition0.95 303.214 12.279 24.693
## fixnoFix:Condition0.95 38.900 12.093 3.217
##
## Correlation matrix not shown by default, as p = 24 > 12.
## Use print(x, correlation=TRUE) or
## vcov(x) if you need it
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
Anova(f1)
## Analysis of Deviance Table (Type II Wald chisquare tests)
##
## Response: n
## Chisq Df Pr(>Chisq)
## fix 500.795 3 < 2.2e-16 ***
## Condition 44.923 5 1.504e-08 ***
## fix:Condition 1411.950 15 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
plot(ggpredict(f1, terms = c("fix", "Condition"), type = "fe"))

Stimulus-based fixation frequency
fixation_prop1 <- c()
for (i in unique(fixation$id)) {
for (j in unique(fixation$Condition)) {
d <- subset(fixation, fixation$id == i & fixation$Condition == j)
s <- sum(d$n)
fixation_prop1 <- rbind(fixation_prop1, mutate(d, prop = n/s))
}
}
ggplot(fixation_prop1, aes(x = fix, y = prop, color = Condition)) + geom_violin() +
geom_point(position = position_dodge(width = .9)) +
stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9))

Stimulus-based fixation frequency (noFix excluded)
fixation2 <- subset(fixation, fixation$fix != "noFix")
fixation_prop2 <- c()
for (i in unique(fixation2$id)) {
for (j in unique(fixation2$Condition)) {
d <- subset(fixation2, fixation2$id == i & fixation2$Condition == j)
s <- sum(d$n)
fixation_prop2 <- rbind(fixation_prop2, mutate(d, prop = n/s))
}
}
ggplot(fixation_prop2, aes(x = fix, y = prop, color = Condition)) + geom_violin() +
geom_point(position = position_dodge(width = .9)) +
stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9))

Stimulus-based fixation frequency (noFix excluded)
fixation3 <- subset(fixation, fixation$fix == "target" | fixation$fix == "distractor")
fixation_prop3 <- c()
for (i in unique(fixation3$id)) {
for (j in unique(fixation3$Condition)) {
d <- subset(fixation3, fixation3$id == i & fixation3$Condition == j)
s <- sum(d$n)
fixation_prop3 <- rbind(fixation_prop3, mutate(d, prop = n/s))
}
}
ggplot(fixation_prop3, aes(x = fix, y = prop, color = Condition)) + geom_violin() +
geom_point(position = position_dodge(width = .9)) +
stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9))
